// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: xguo

#include <string>
#include <memory>
#include <chrono>

#include "coin2/exchange/base/api_base/asio_http_driver.h"
#include "coin2/exchange/base/api_base/asio_http_context.h"
#include "coin2/exchange/base/market/market_exchange_api.h"
#include "coin2/exchange/order/connection.pb.h"
#include "coin2/exchange/prex_futures/api_order/native_private_client.h"

using coin2::exchange::base::api_base::NativeHttpAsioDriver;
using coin2::exchange::base::market::MarketExchangeApi;
using coin2::exchange::order::OrderConnectionConfig;
using RestParams = coin2::exchange::order::PrexFuturesRestParams;

PrexFuturesNativePrivateClient* GetClient() {
  static std::unique_ptr<PrexFuturesNativePrivateClient> client;
  if (client) {
    return client.get();
  } else {
    auto mea = MarketExchangeApi::FromString("Futures.Prex.v1");
    OrderConnectionConfig config;
    config.set_rest_host("10.21.4.16");
    config.set_rest_host_port(8443);
    config.set_key_filepath("/home/xguo/config/trade_key.json");
    client = std::make_unique<PrexFuturesNativePrivateClient>(mea, config);
    return client.get();
  }
}



std::shared_ptr<AsioHttpContext> CreateRequest() {
  auto mea = MarketExchangeApi::FromString("Futures.Prex.v1");
  OrderConnectionConfig config;
  config.set_rest_host("10.21.4.16");
  config.set_rest_host_port(8443);
  config.set_key_filepath("/home/xguo/config/trade_key.json");

  PrexFuturesNativePrivateClient client(mea, config);

  RestParams params;
  params.set_symbol("BTCUSD.PERP");
  params.set_order_side("ORDER_SIDE_BUY");
  params.set_price("100");
  params.set_qty("100");
  params.set_order_type("ORDER_TYPE_LIMIT");
  params.set_time_in_force("TIME_IN_FORCE_GOOD_TILL_CANCEL");
  params.set_exec_inst("EXEC_INST_PARTICIPATE_DO_NOT_INITIATE");
  params.set_client_order_id("xguo");

  auto req = GetClient()->PlaceOrder(params);
  LOG(INFO) << req->ToProto().DebugString();

  // auto req = AsioHttpContext::NewGet(host, port, bind_ip, target);
  req->handler = [](const std::shared_ptr<AsioHttpContext>& ctx) {
    //LOG(INFO) << "received!";
    // LOG(INFO) << ctx->ToProto().DebugString();
  };
  return std::shared_ptr<AsioHttpContext>(req);
}

void run(boost::asio::io_context* ioc, NativeHttpAsioDriver* http_driver) {
  static auto start_ts = GetCurrentTimestamp();

  auto req = CreateRequest();
  http_driver->PostAsyncContext(req);
  if (GetCurrentTimestamp() - start_ts < 30e9) {
    ioc->post([ioc, http_driver](){ run(ioc, http_driver); });
  }
}

int main() {
  auto mea = MarketExchangeApi::FromString("Futures.Prex.v1");
  OrderConnectionConfig config;
  boost::asio::io_context ioc;
  auto http_driver = std::make_unique<NativeHttpAsioDriver>(&ioc, mea, config);
  http_driver->Start();

  boost::asio::deadline_timer timer(ioc, boost::posix_time::seconds(40));
  timer.async_wait([&http_driver](const boost::system::error_code&) mutable { http_driver.reset(); });

  ioc.post([&]() { run(&ioc, http_driver.get()); });
  ioc.run();
  return 0;
}
